using System;
using System.Collections;
using System.Collections.Generic;
using GameFramework.Procedure;
using GameFramework.Fsm;
using Sirenix.OdinInspector.Editor;
using Sirenix.Serialization;
using UnityGameFramework.Runtime;

/// <summary>
/// ��Ϸ����
/// </summary>
public abstract class GameBaseProcedure : ProcedureBase
{
    protected IFsm<IProcedureManager> mProcedureOwner;

    protected override void OnInit(IFsm<IProcedureManager> procedureOwner)
    {
        base.OnInit(procedureOwner);
    }

    protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
    {
        base.OnEnter(procedureOwner);
        mProcedureOwner = procedureOwner;
    }

    protected sealed override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
        float realElapseSeconds)
    {
        var next = nextProcedureName;
        var data = procedureUserData;
        if (!string.IsNullOrEmpty(next))
        {
            nextProcedureName = null;
            procedureUserData = null;
            var type = Type.GetType(next);
            if (type == null || !type.IsSubclassOf(typeof(GameBaseProcedure)) || type.IsAbstract)
                throw new Exception($"ChangeProcedure error,type is {type.Name}");

            if (type == typeof(LuaProcedure))
            {
                if (string.IsNullOrEmpty(data))
                    throw new Exception("LuaProcedure error");
                procedureOwner.SetData<VarString>("luaProcedureName", $"procedure.{data}");
                if (!typeof(LuaProcedure).Equals(this.GetType()))
                {
                    ChangeState<LuaProcedure>(procedureOwner);
                    return;
                }
                ChangeState<NewLuaProcedure>(procedureOwner);
                return;
            }

            ChangeState(procedureOwner, type);
            return;
        }

        OnNewUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
    }

    protected virtual void OnNewUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds)
    {}

    public static void ChangeState(string procedureName,string userData = null)
    {
        nextProcedureName = procedureName;
        procedureUserData = userData;
    }

    private static string nextProcedureName = null;
    private static string procedureUserData = null;
}